import { Context, Next } from 'koa';
import { getIdByToken } from '../jwt/jwtService';
import { getRedis } from '../redis/Redis';
import Result from '../vo/result';
import { ResultCode, ResultCodeMessages } from '../enums/resultCode';
import { whiteListUser } from '../whiteList/whiteListUser';
import { getUserByIdService } from '../service/UserService';

const isWhiteList = (url: string): boolean => {
  return whiteListUser.some(protectedUrl => {
    const regex = new RegExp(`^${protectedUrl.replace('*', '.*')}$`);
    return regex.test(url);
  });
};

const extractTokenFromHeader = (request: any): string | undefined => {
  const [type, token] = request.headers.authorization?.split(' ') ?? [];
  return type === 'Bearer' ? token : undefined;
};
const UserGuard = async (ctx: Context, next: Next) => {
  if(ctx.headers['clienttype'] !== 'web' && ctx.headers['clienttype'] !== 'miniApp') {
    ctx.body = Result.fail(ResultCode.PARAMS_ERROR, ResultCodeMessages[ResultCode.PARAMS_ERROR]);
    return;
  }
  if (isWhiteList(ctx.url) || !ctx.url.startsWith('/api') || ctx.headers['clienttype'] !== 'miniApp') {
    await next();
  } else {
    const token = extractTokenFromHeader(ctx);
    if (!token) ctx.body = Result.fail(ResultCode.MISSING_TOKEN, ResultCodeMessages[ResultCode.MISSING_TOKEN]);
    if (token) {
      const id = getIdByToken(token);
      const redisTokenPromise = await getRedis(`token_user_login_${id}`);
      if (redisTokenPromise !== token) {
        ctx.body = Result.fail(ResultCode.TOKEN_ERROR, ResultCodeMessages[ResultCode.TOKEN_ERROR]);
        return;
      }

      if (redisTokenPromise === token) {
        //查询这个token解析出来的id是否存在Admin表中
        const res = await getUserByIdService(id);
        if (res?.code === '1' && res?.data?.status === 0) {
          await next();
        } else {
          ctx.body = Result.fail(ResultCode.USER_NOT_EXIST, ResultCodeMessages[ResultCode.USER_NOT_EXIST]);
        }
      }
    }
  }
};

export default UserGuard;